#include "Tool.h"
#include <math.h>

//根据分压电路转换成电阻
//输入 12位AD, 输出对应的 电阻值
//根据 AD采样值, 求上拉电阻

_Pt1000_State Pt1000_State;

double AD_Convert_R(uint32_t ad)
{
    int temp_int;
    double temp;
    double x;
    double Vdd = 5.0;
    double V_Div = 0;

    temp = ad;
    if(temp != 0)
    { //根据分压电路,得出AD转电阻的公式
        // V_Div = Vdd / 1023.0 * temp; //1023: 10位AD; 分压 = VDD / 1023 * AD
        // V_Div = Vdd / 4095.0 * temp; //4095: 12位AD; 分压 = VDD / 4095 * AD
        V_Div = Vdd / 4095.0 * temp; //4095(通过 实际测量5v对应的AD上限值): 12位AD; 分压 = VDD / 4095 * AD

        V_Div *= 1000;
        temp_int = V_Div;
        V_Div = temp_int;
        V_Div /= 1000.0;

        x = V_Div;
        // V_Div = 0.07591042134640329*x*x+0.6397938329589505*x+0.37837459625621633;
        V_Div = -2390.309263086916*x*x*x*x*x*x*x*x+56328.69899795618*x*x*x*x*x*x*x-580067.2896779225*x*x*x*x*x*x+3409434.783470712*x*x*x*x*x-12510037.034496747*x*x*x*x+29343105.195064504*x*x*x-42965938.74955403*x*x+35908314.11860773*x-13113974.973818667; //电压拟合补偿

        // temp = 1000.0 / V_Div * Vdd - 1000.0; //上拉电阻 = 分压电阻 / 分压 * VDD - 分压电阻
		temp = V_Div / (Vdd - V_Div)  * (1000.0 * 0.985); //原理图上的上拉电阻是1k   分压电阻(下拉电阻) = 分压 / ((VDD - 分压) * 上拉电阻);  R_Div = V_Div / (Vdd - V_Div)  * R_Up
        //(1000.0 * 0.985): 1.0k 1%电阻精度补偿 
    }
    return temp;
}
//卡马克快速求平方根的倒数(替换标准库sqrt函数): 比标准库函数快4倍
float InvSqrt(float number)
{
    long i;
    float x2, y;

    x2 = number * 0.5;
    y  = number;
    i  = *(long *)&y; //evil floating point bit level hacking
    i  = 0x5f3759df - (i >> 1); // 计算第一个近似根 // what the fuck?
    y  = *(float *)&i;
    y  = y * (1.5 - (x2 * y * y)); //牛顿迭代法 // 1st iteration 
    y  = y * (1.5 - (x2 * y * y)); //2nd iteration, this can be removed

    return y;
}

//将电压转成电阻
//输入的 VDD = 电阻1k对应的分压
//需要 VDD * 2,用于计算出电源电压
double V_Convert_R(uint32_t vdd,uint32_t v)
{
    double temp1;
    double temp2;
    
    temp1 = vdd;
    temp2 = v;
    if(temp2 != 0) temp2 = (temp1 / temp2);
    temp2 *= 2.0; //VDD = 2 * 1k电阻对应的分压

    temp2 *= 1000.0;
    temp2 -= 1000.0;
    return temp2;
}

//Pt1000电阻转C温度值
//Pt1000铂电阻的一元二次解温度公式
//输入电阻值, 例如 1000.000
//返回 C温度(有符号值),有效位小数点后2位
double Quadratic(float R_x)
{
    float a;
    float b;
    float c;
    float x = 0.0;

    if(R_x <= 100)
    { //判断Pt1000电阻 <= 100, 就认为铂电阻短路
        x = -222.935332;
        Pt1000_State = Pt1000_Short;
    }
    else if (R_x >= 5000)
    { //判断Pt1000电阻 >= 5k, 认为电阻开路
        x = 1256.896275;
        Pt1000_State = Pt1000_Open;
    }
    else
    {
        a = 1000.000;
        a *= -0.0000005775;
        b = 1000.000;
        b *= 0.0039083;
        c = 1000.000 - R_x;
        
        x = b * b - (4.0 * a * c);
        
		if(InvSqrt(x) != 0) x = (-b + 1.0/InvSqrt(x)) / (2.0 * a);
        Pt1000_State = Pt1000_Normal;
    }

    return x;
}



//将摄氏度转华氏度
double CTemp_Convert_FTemp(double F_temp)
{
    F_temp *= 1.8;
    F_temp += 32;

    return F_temp;
}








